#!/bin/bash
#(c) Copyright 2008 Barry Kauler, puppylinux.com
# Masaki Shinomiya <shino@pos.to>, karl godt
#2008 Lesser GPL licence v2 (see /usr/share/doc/legal)
# 
#/sbin/pup_event_frontend_d creates a desktop icon and copy of this script for each drive, ex:
# for drive sda: cp -a /usr/local/bin/drive_all /root/.pup_event/drive_sda/AppRun
#this script is launched by pup_event_frontend_d when the icon is first created. also,
#this script is launched when user clicks on deskop icon (former is configurable,
# see /usr/sbin/eventmanager.
#passed param is category of drive: card, floppy, optical, usbdrv, drive.

#v403 icon menu, can call with 'unmount', 'eventmanager' and 'pmount_<DRV_CATEGORY>' params.
#110720 should not open a layer inside aufs, ex: session saved entire partition, desktop drive icon is /initrd/pup_rw.
#110721 detect if have clicked on a close-box of mounted partition.
#120110 running as fido, popup password box changes mouse pointer position, need read before run sudo.
#120516 pup_event_frontend_d may call here when a drive plugged in, fix handling of automounting.

#exec &> /tmp/drive_all.log ; set -x #debug

export LANG	# need to restart pmount with correct locale
export TEXTDOMAIN=drive_all
export OUTPUT_CHARSET=UTF-8
. gettext.sh

[ "`whoami`" != "root" ] && exec sudo -A ${0} ${@} #110505

grep -q -m1 -i 'rox' /usr/local/bin/defaultfilemanager && ROX_FILER=yes

unmount_func() {
 [ "$ROX_FILER" = "yes" ] && rox -D $MNTPT
 sync
 while [ 1 ];do
  umount.crypto_LUKS "$MNTPT" || umount "$MNTPT"
  umVAL=$?
  #fix zombie process prevents partition unmount, invisible to fuser...
  if [ $umVAL -ne 0 ];then
   #120129 karl godt: fix ZOMBIES, see http://murga-linux.com/puppy/viewtopic.php?t=71767&start=420 ...
    ZOMBIES="`ps -H -A | grep '<defunct>' | sed 's/^[[:blank:]]*//;s/  /|/g' | grep -v '|||' | cut -f 1 -d ' ' | tr '\n' ' '`"
   for ONEZOMBIE in $ZOMBIES
   do
    echo "Killing parentless zombie process $ONEZOMBIE"
    kill $ONEZOMBIE
   done
   umount $MNTPT ; umVAL=$?
  fi
  #rare ocassion, partition got unmounted before umount runs above...
  mount | grep -q "${MNTPT} " || umVAL=0 #not mounted
  if [ $umVAL -ne 0 ];then
   EXTRAMSG0="`fuser -v -m $MNTPT`"  
   if [ "$EXTRAMSG0" = "" ];then
    /usr/lib/gtkdialog/box_ok "$(gettext 'Puppy drive manager')" error  "$(gettext 'FAILURE! In the case of removable media, the most
common reason is the media is not currently inserted.
If so, please remedy.')"
   else
    xmessage -bg "#ff99ff" -title "$(gettext 'Puppy drive manager: FAIL')" -center -buttons "$(gettext 'KILL')":10,"$(gettext 'EXIT')":20 "$(gettext 'FAILURE!')
$(gettext 'One or more processes (programs) are currently
using the partition. Here they are:')
${EXTRAMSG0}

$(gettext "If you press the 'KILL' button, Puppy will attempt to
kill the offending programs for you. Only do this as a
last resort.")
$(gettext "Firstly you should try to close the programs
manually, so do not press 'KILL'.")
$(gettext "PLEASE PRESS THE 'EXIT' BUTTON!")"
    if [ $? -eq 10 ];then
     fuser -k -m $MNTPT
     continue
    fi
   fi
  else
   [ "$DRV_CATEGORY" = "optical" ]  && eject /dev/$ONEDRVNAME
  fi
  break
 done
}

PARAM1="$1"
FSTYPE="$2" #see pup_event_frontend_d.

#extract drive name from end of the script name...
#note, when click on desktop icon, /root/.pup_event/drive_<ONEDRVNAME> is executed,
#however a script may run /root/.pup_event/drive_<ONEDRVNAME>/AppRun ...
ONEDRVNAME=$(dirname $0|sed -e 's/^.*_//')
if [ "`echo "${PARAM1}" | grep 'pmount_'`" != "" ];then #v403 chose pmount from drive icon menu.
 DRV_CATEGORY="`echo -n "${PARAM1}" | cut -f 2 -d '_'`"
 if [ "`pidof gtkdialog_pmount`" != "" ];then #if pmount running, kill it.
  killall gtkdialog_pmount 2>/dev/null
  sleep 0.1
 fi
 exec pmount $ONEDRVNAME
fi

#110721 detect if have clicked on a close-box of mounted partition...
#when left-click desktop icon, param1 passed this script: drive|card|floppy|optical|usbdrv
# and param2 has the fs type...
case $PARAM1 in
 drive|card|floppy|optical|usbdrv)
  MNTPT="`mount | grep -m1 -E "^/dev/${ONEDRVNAME} |^/dev/mapper/lukspartition_${ONEDRVNAME} " | tr -s ' ' | cut -f 3 -d ' '`"
  if [ "$MNTPT" ];then
   read CURPOSX CURPOSY <<< `getcurpos`
   #get coords of desktop icon...
   drPTN=">/root/.pup_event/drive_${ONEDRVNAME}<"
   PPENTRY="`grep "$drPTN" /root/Choices/ROX-Filer/PuppyPin`"
   if [ "$PPENTRY" ];then
    xleft="`echo -n "$PPENTRY" | grep -o ' x="[0-9]*"' | cut -f 2 -d '"'`" #'geany
    ytop="`echo -n "$PPENTRY" | grep -o ' y="[0-9]*"' | cut -f 2 -d '"'`" #'geany
    #hmmm, have to apply correction to cursor position...
    CURPOSX=$(($CURPOSX + 24))
    CURPOSY=$(($CURPOSY + 32))
    xcloseleft=$(($xleft + 35)) #close-box is 13x13 pixels, want bigger pickup area.
    xcloseright=$(($xleft + 53))
    yclosetop=$(($ytop - 5))
    yclosebottom=$(($ytop + 13))
    if [ $CURPOSX -ge $xcloseleft ];then
     if [ $CURPOSX -le $xcloseright ];then
      if [ $CURPOSY -ge $yclosetop ];then
       if [ $CURPOSY -le $yclosebottom ];then
        PARAM1="unmount"
       fi
      fi
     fi
    fi
   fi
  fi
 ;;
esac

if [ "$PARAM1" = "eventmanager" ];then #v403 chosen from drive icon menu.
	exec eventmanager desktop
fi

if [ "$PARAM1" = "unmount" ];then #v403 chose unmount from drive icon menu.
 MNTPT="`mount | grep -m1 -E "^/dev/${ONEDRVNAME} |^/dev/mapper/lukspartition_${ONEDRVNAME} " | tr -s ' ' | cut -f 3 -d ' '`"
 DRV_CATEGORY=$(probedisk $ONEDRVNAME | cut -d'|' -f 2)
 [ "$MNTPT" = "" -a "$DRV_CATEGORY" = "optical" ] && eject /dev/$ONEDRVNAME
 [ "$MNTPT" = "" ] && exit #precaution.
 if [ "$MNTPT" = "/" -o "`echo "$MNTPT" | grep '/initrd/'`" != "" ];then
  /usr/lib/gtkdialog/box_ok "$(gettext 'Puppy drive manager')" error  "$(eval_gettext "/dev/\${ONEDRVNAME} mounted on \${MNTPT}
is in use by Puppy. You cannot unmount it.")"
  exit
 fi
 unmount_func
 exit
fi

#v424 have added right-click menu item to unmount all partitions (see pup_event_frontend_d)...
if [ "$PARAM1" = "unmountall" ];then
 for MNTPT in `mount | grep '^/dev/' | grep -vE '^/dev/loop|^/dev/ram' | cut -f 3 -d ' ' | grep -v '^/initrd/' | grep -v '^/$' | tr '\n' ' '`
 do
  unmount_func
 done
 exit
fi

DRV_CATEGORY="${PARAM1}"
[ "$DRV_CATEGORY" = "" ] && DRV_CATEGORY="drive" #precaution.
[ "$DRV_CATEGORY" = "all" ] && DRV_CATEGORY="drive" #precaution.

. /etc/eventmanager
. /etc/rc.d/functions_x

#if HOTPLUGON=false (see /etc/eventmanager and /sbin/pup_eventd) then there will only
#be one icon on the desktop, labelled 'drives' and handler script is /usr/local/bin/drive_drives
if [ "$ONEDRVNAME" = "drives" ];then
 if [ "`pidof gtkdialog_pmount`" != "" ];then #if pmount running, kill it.
  killall gtkdialog_pmount 2>/dev/null
  sleep 0.1
 fi
 exec pmount $DRV_CATEGORY
fi

#oh, now have to analyse the media, decide what app to run...

optical_func() {

  mount | grep "^/dev/${ONEDRVNAME} " && return #already mounted
  DRIVEINFO="$(dvd+rw-mediainfo /dev/${ONEDRVNAME})"
  EXITCODE=$?
  DRIVETYPE="$(echo "$DRIVEINFO" | grep 'INQUIRY:')"
  DRIVETYPE2='['"${DRIVETYPE#*[}"

  echo "/dev/${ONEDRVNAME} filesystem: $FSTYPE " # debug
  echo "dvd+rw-mediainfo exit code: $EXITCODE"   # debug
  echo "${DRIVETYPE}" # debug

  case $EXITCODE in
    150) # :-( not a DVD unit
        case "${DRIVETYPE}" in *CD-R*) CDR="true" ;; esac
        ;;
    251) # :-( no media mounted
        # cd/dvd might be blank
        cddetect_quick -d/dev/${ONEDRVNAME} || exit 1
        # might be and old dvd drive and the disc a DVD9/DL-DVD
        echo "===================================="
        echo "* The disc in /dev/${ONEDRVNAME} is blank (or may be unsupported by your dvd drive)..."
        echo "===================================="
        /usr/lib/gtkdialog/box_yesno --yes-first --ok-cancel --image-icon cdrom.svg --yes-label "Run Pburn" --yes-icon cdrom.svg \
        "Blank disk" "$DRIVETYPE2" "The disc in /dev/${ONEDRVNAME} is blank" "(or may be the case that is not supported by your dvd drive," "could be a double-layer DVD, and your dvd drive too old...)"
        [ $? -eq 0 ] && which pburn &>/dev/null && exec pburn
        exit
        ;;
    252) CDR="true" ;; # :-( non-DVD media mounted
  esac

  ####### CDS ########
  if [ "$CDR" = "true" ] ; then
     cddetect -d/dev/${ONEDRVNAME} #-q
     RETVAL=$?
     echo "cddetect exit code: $RETVAL"
     case $RETVAL in
        1|50) #1) audio 50) mixed. we don't want to mount it but we'll see if it plays
          [ ${RETVAL} -eq 50 ] && mountcd='--extra-button Mount'
          echo "/dev/${ONEDRVNAME}: Audio CD (most likely)"
          /usr/lib/gtkdialog/box_yesno --yes-first --ok-cancel --image-icon cd_audio.svg --yes-label "Play" --yes-icon cd_audio.svg $mountcd \
          "CD Audio detected..." "An audio CD has been detected. Do you want to play it?"
          case $? in
            0) ln -snf /dev/${ONEDRVNAME} /dev/cdrom
               exec defaultcdplayer cdda:// ;;
            2) true   ;; #continue to mount drive
            *) exit 1 ;; #close/cancel
          esac
          ;;
        255) #might be blank, double check it's there #140712
          cddetect_quick -d/dev/${ONEDRVNAME} || exit 1
          /usr/lib/gtkdialog/box_yesno --yes-first --ok-cancel --image-icon cdrom.svg --yes-label "Run Pburn" --yes-icon cdrom.svg \
          "Blank CD (most likely)" "$DRIVETYPE2" "The disc in /dev/${ONEDRVNAME} is blank (most likely)" "(if you know it's not blank then the CD might be damaged...)"
          [ $? -eq 0 ] && which pburn &>/dev/null && exec pburn
          exit
          ;;
     esac

  ####### DVDs and more ######
  else
     # check if it's blank
     ITSBLANK=$(echo "$DRIVEINFO" | grep -i 'Disc status:' | grep -i 'blank')
     if [ "$ITSBLANK" ] ; then
        echo "/dev/${ONEDRVNAME}: DVD is blank"
        /usr/lib/gtkdialog/box_yesno --yes-first --ok-cancel --image-icon cdrom.svg --yes-label "Run Pburn" --yes-icon cdrom.svg "Blank DVD" "The disk /dev/${ONEDRVNAME} is blank..."
        [ $? -eq 0 ] && which pburn &>/dev/null && exec pburn
        exit
     fi
     # --
     # mount and look for 'video_ts' directory (dir should contain file video_ts.ifo)...
     OPTICALMOUNTED="true" #don't try to mount the drive afterwards
     echo "Trying to mount /dev/${ONEDRVNAME}"
     mkdir -p /mnt/${ONEDRVNAME}
     mount -t udf /dev/${ONEDRVNAME} /mnt/${ONEDRVNAME} || mount -t iso9660 /dev/${ONEDRVNAME} /mnt/${ONEDRVNAME}
     RETVALX=$?
     [ ${RETVALX} -ne 0 ] && return
     if [ -d /mnt/${ONEDRVNAME}/video_ts -o -d /mnt/${ONEDRVNAME}/VIDEO_TS ] ; then
        /usr/lib/gtkdialog/box_yesno --yes-first --ok-cancel --image-icon video.svg --yes-label "Play" --yes-icon cdrom.svg --extra-button Mount \
        "Video DVD detected..." "This seems to be a Video DVD, do you want to play it?"
        case $? in
          0) #play
            umount /mnt/${ONEDRVNAME} ; echo "/dev/${ONEDRVNAME}: Video DVD detected"
            ln -snf /dev/${ONEDRVNAME} /dev/dvd
            exec defaultmediaplayer dvd://
            ;;
          2) OPTICALMOUNTED="true" ;; #keep mounted
          *) umount /mnt/${ONEDRVNAME} ; exit 1 ;;
        esac
     else
        if [ "$FSTYPE" = "0" -o "$FRONTEND_CHANGE" ] ; then
          umount /mnt/${ONEDRVNAME}
        fi
     fi
  fi
}

if fx_drv_is_optical ${ONEDRVNAME} ; then
	optical_func
fi

#FSTYPE=0 -> ICONDESK=true ICONPARTITIONS=false
#exec pmount if called directly by FRONTEND_CHANGE
if [ "$FSTYPE" = "0" -o "$FRONTEND_CHANGE" ] ; then
	if [ "`pidof gtkdialog_pmount`" != "" ];then #if pmount running, kill it.
		killall gtkdialog_pmount 2>/dev/null
		sleep 0.1
	fi
	exec pmount $ONEDRVNAME
fi

#if dropped down here, it is likely to be a data partition...

#120516 pup_event_frontend_d may call here when a drive plugged in, but only passes one parameter (PARAM1). want FSTYPE also...
xONEDRVNAME=${ONEDRVNAME}
if [ "$FSTYPE" != "" ];then
 xFSTYPE=${FSTYPE}
else
 xFSTYPE=$(probepart -m "${ONEDRVNAME}" | cut -f 2 -d '|')
fi

#if it is a mountable partition then mount and open with rox. If already mntd then open in rox...
EXITFLAG=no
if [ "$xFSTYPE" ] ; then
 if [ "`df | grep "^/dev/${ONEDRVNAME} "`" = "" ];then
  #not mounted...
  mkdir -p /mnt/$xONEDRVNAME
  case $xFSTYPE in
   iso9660|udf)
     if [ "$OPTICALMOUNTED" ] ; then
       RETVAL1=${RETVALX}
     else
       mount -t udf /dev/$xONEDRVNAME /mnt/$xONEDRVNAME || mount -t iso9660 /dev/$xONEDRVNAME /mnt/$xONEDRVNAME
       RETVAL1=$?
     fi
     ;;
   *)
    mount -t $xFSTYPE /dev/$xONEDRVNAME /mnt/$xONEDRVNAME
    RETVAL1=$?
    ;;
  esac
  if [ $RETVAL1 -eq 0 ];then
   defaultfilemanager /mnt/$xONEDRVNAME &
   EXITFLAG=yes
  fi
 else
  #mounted...
  MNTPT="`mount | grep -m1 "^/dev/${ONEDRVNAME} " | cut -f 3 -d ' '`"
  if [ -h /mnt/home ];then
   [ "`readlink /mnt/home`" = "$MNTPT" ] && MNTPT="/mnt/home"
  fi
  #110720 should not open a layer inside aufs, ex: session saved entire partition, desktop drive icon is /initrd/pup_rw...
  case $MNTPT in /initrd/pup_*) MNTPT="/" ;; esac
  defaultfilemanager $MNTPT &
  EXITFLAG=yes
 fi
fi
[ "$EXITFLAG" = "yes" ] && exit

#NOTE: if pmount already running, don't really want to kill then restart,
# just want to bring the window up if it's minimised ...how?

if [ "`pidof gtkdialog_pmount`" != "" ];then #if pmount running, kill it.
 killall gtkdialog_pmount 2>/dev/null
 sleep 0.1
fi
exec pmount $ONEDRVNAME

###END###
